package com.torry.edss.application.biz.impl;

import com.torry.boot.common.util.Preconditions;
import com.torry.edss.application.biz.TacticBiz;
import com.torry.edss.application.exception.ReplayExceptionEnum;
import com.torry.edss.domain.annotations.TacticBean;
import com.torry.edss.domain.enums.TacticMode;
import com.torry.edss.domain.service.TacticService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author torry.wang
 */
@Service
public class TacticBizImpl implements TacticBiz {

    @Resource
    private ApplicationContext applicationContext;
    private static final Map<String, TacticService> TACTICS_SERVICE_BEANS = new HashMap<>();

    @PostConstruct
    public void cacheResBusinessOperatorBeans() {
        Map<String, TacticService> beansMap = applicationContext.getBeansOfType(TacticService.class);
        beansMap.values().forEach(bean -> {
            TacticBean tacticBean = bean.getClass().getDeclaredAnnotation(TacticBean.class);
            if (tacticBean != null) {
                TACTICS_SERVICE_BEANS.put(tacticBean.mode().name(), bean);
            }
        });
    }

    private TacticService routeToSpecifiedService(TacticMode mode) {
        TacticService tacticService = TACTICS_SERVICE_BEANS.get(mode.name());
        Preconditions.ofNotNull(tacticService, ReplayExceptionEnum.CANNOT_FOUND_TACTIC_MODE_BEAN, mode.name());
        return TACTICS_SERVICE_BEANS.get(mode.name());
    }


    @Override
    public boolean realTimePicking(TacticMode tacticMode) {
        return routeToSpecifiedService(tacticMode).realTimePicking();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean hisPicking(String date, TacticMode tacticMode) {
        return routeToSpecifiedService(tacticMode).hisPicking(date);
    }

    @Override
    public boolean refreshProfit(TacticMode tacticMode,Integer days) {
        return routeToSpecifiedService(tacticMode).refreshProfit(days);
    }
}
